# -*- coding: utf-8 -*-
# Author   : ZhangQing
# Time     : 2025-08-05 23:27
# File     : auth.py
# Project  : codebuddy_craft
# Desc     :
# backend/schemas/auth.py
# backend/schemas/auth.py (更新版)
"""
认证数据模式定义 🔐

定义认证相关的请求和响应数据结构
"""

from pydantic import BaseModel, Field, EmailStr, validator
from typing import Optional, Dict, Any
from datetime import datetime

# 从 user.py 导入 UserResponse
from .user import UserResponse


class LoginRequest(BaseModel):
    """登录请求模型 🔑"""
    username: str = Field(..., min_length=3, max_length=50, description="用户名或邮箱")
    password: str = Field(..., min_length=6, description="密码")
    remember_me: bool = Field(default=False, description="记住我")

    @validator('username')
    def validate_username(cls, v):
        """验证用户名"""
        return v.strip().lower()


class RegisterRequest(BaseModel):
    """注册请求模型 📝"""
    username: str = Field(..., min_length=3, max_length=50, description="用户名")
    email: EmailStr = Field(..., description="邮箱地址")
    password: str = Field(..., min_length=8, description="密码")
    full_name: Optional[str] = Field(None, max_length=100, description="全名")
    agree_terms: bool = Field(..., description="同意服务条款")

    @validator('username')
    def validate_username(cls, v):
        """验证用户名"""
        import re
        if not re.match(r'^[a-zA-Z0-9_-]+$', v):
            raise ValueError('用户名只能包含字母、数字、下划线和连字符')
        return v.strip().lower()

    @validator('full_name')
    def validate_full_name(cls, v):
        """验证全名"""
        if v:
            return v.strip()
        return v

    @validator('agree_terms')
    def validate_agree_terms(cls, v):
        """验证服务条款同意"""
        if not v:
            raise ValueError('必须同意服务条款才能注册')
        return v


class TokenResponse(BaseModel):
    """令牌响应模型 🎫"""
    access_token: str = Field(..., description="访问令牌")
    refresh_token: str = Field(..., description="刷新令牌")
    token_type: str = Field(default="bearer", description="令牌类型")
    expires_in: int = Field(..., description="过期时间(秒)")
    user: UserResponse = Field(..., description="用户信息")


class RefreshTokenRequest(BaseModel):
    """刷新令牌请求模型 🔄"""
    refresh_token: str = Field(..., description="刷新令牌")


class ChangePasswordRequest(BaseModel):
    """修改密码请求模型 🔐"""
    current_password: str = Field(..., description="当前密码")
    new_password: str = Field(..., min_length=8, description="新密码")
    confirm_password: str = Field(..., description="确认新密码")

    @validator('new_password')
    def validate_new_password(cls, v, values):
        """验证新密码"""
        current_password = values.get('current_password')
        if current_password and v == current_password:
            raise ValueError('新密码不能与当前密码相同')
        return v

    @validator('confirm_password')
    def validate_confirm_password(cls, v, values):
        """验证确认密码"""
        new_password = values.get('new_password')
        if new_password and v != new_password:
            raise ValueError('确认密码与新密码不匹配')
        return v


class PasswordResetRequest(BaseModel):
    """密码重置请求模型 🔄"""
    email: EmailStr = Field(..., description="邮箱地址")


class PasswordResetConfirm(BaseModel):
    """密码重置确认模型 ✅"""
    token: str = Field(..., description="重置令牌")
    new_password: str = Field(..., min_length=8, description="新密码")
    confirm_password: str = Field(..., description="确认新密码")

    @validator('confirm_password')
    def validate_confirm_password(cls, v, values):
        """验证确认密码"""
        new_password = values.get('new_password')
        if new_password and v != new_password:
            raise ValueError('确认密码与新密码不匹配')
        return v


class EmailVerificationRequest(BaseModel):
    """邮箱验证请求模型 📧"""
    token: str = Field(..., description="验证令牌")


class LoginResponse(BaseModel):
    """登录响应模型 🎉"""
    success: bool = Field(..., description="登录是否成功")
    message: str = Field(..., description="响应消息")
    tokens: Optional[TokenResponse] = Field(None, description="令牌信息")
    user: Optional[UserResponse] = Field(None, description="用户信息")

    class Config:
        from_attributes = True
